package com.java.module.chat.service.impl;

import java.util.List;
import java.util.Map;
import java.util.Objects;

import com.alibaba.fastjson.JSONObject;
import com.java.module.chat.util.*;
import com.java.common.utils.redis.RedisCache;
import com.java.module.chat.domain.GroupUser;
import com.java.module.chat.domain.dto.SessionDTO;
import com.java.module.chat.mapper.GroupUserMapper;
import com.java.module.chat.domain.ChatMessage;
import com.java.module.chat.domain.Session;
import com.java.module.chat.domain.dto.ChatMessageDTO;
import com.java.module.chat.domain.vo.ChatMessageVO;
import com.java.module.chat.mapper.ChatMessageMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.java.common.lang.domain.ReturnVO;
import com.java.common.lang.domain.entity.User;
import com.java.common.lang.exception.BaseException;
import com.java.common.utils.DateUtils;
import com.java.common.utils.WebKit;
import com.java.common.utils.bean.BeanUtils;
import com.java.common.utils.html.HtmlKit;
import com.java.module.chat.service.IChatMessageService;
import com.java.module.chat.service.IDisableWordService;
import com.java.module.chat.service.ISessionService;
import com.java.module.chat.util.netty.ChatKit;
import com.java.module.user.service.IUserService;
import com.vdurmont.emoji.EmojiParser;



/**
 * 聊天：消息Service业务层处理
 * 
 * @author Administrator
 * @date 2021-05-13
 */
@Slf4j
@Service
public class ChatMessageServiceImpl implements IChatMessageService {

    private static final String MESSAGE_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

    @Autowired
    private ChatMessageMapper chatMessageMapper;

    @Autowired
    private ISessionService sessionSrv;

    @Autowired
    private IDisableWordService disWordSrv;

    @Autowired
    private IUserService userSrv;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IUserService userService;


    @Autowired
    private GroupUserMapper groupUserMapper;

    @Override
    public ChatMessage selectChatMessageById(Long messageId) {
        return chatMessageMapper.selectChatMessageById(messageId);
    }

    @Override
    public List<ChatMessage> selectChatMessageList(ChatMessage chatMessage) {
        return chatMessageMapper.selectChatMessageList(chatMessage);
    }

    /**
     * 消息列表
     */
    @Override
    public List<ChatMessageVO> selectChatMessageHistory(ChatMessage chatMessage) {
        List<ChatMessageVO> list = chatMessageMapper.selectChatMessageHistory(chatMessage);
        Long msgFromUid = chatMessage.getMsgFromUid();
        list.stream().forEach(msg -> setMessage(msgFromUid, msg));
        return list;
    }

    /**
     * 查询单个聊天：消息
     * 
     * @param chatMessage 聊天：消息
     * @return 聊天：消息
     */
    @Override
    public ChatMessage selectChatMessage(ChatMessage chatMessage) {
        return chatMessageMapper.selectChatMessage(chatMessage);
    }

    /**
     * 新增聊天：消息
     * 
     * @param chatMessage 聊天：消息
     * @return 结果
     */
    @Override
    public int insertChatMessage(ChatMessage chatMessage) {
        chatMessage.setCreateTime(DateUtils.getNowDate());
        String msgContent = chatMessage.getMsgContent();
        chatMessage.setMsgStatus(MsgStatusEnum.UNREAD.getMsgStatus());
        if (MsgTypeEnum.TEXT.getMsgType().equals(chatMessage.getMsgType())) {
            // 将表情转换成对应别名字符
            msgContent = disWordSrv.filterDisableWord(msgContent);
            msgContent = EmojiParser.parseToAliases(msgContent);
            chatMessage.setMsgContent(msgContent);
        } else {
            chatMessage.setMsgContent(HtmlKit.getDbFilePath(msgContent, WebKit.getBasePath()));
        }
        return chatMessageMapper.insertChatMessage(chatMessage);
    }

    /**
     * 修改聊天：消息
     * 
     * @param chatMessage 聊天：消息
     * @return 结果
     */
    @Override
    public int updateChatMessage(ChatMessage chatMessage) {
        chatMessage.setUpdateTime(DateUtils.getNowDate());
        return chatMessageMapper.updateChatMessage(chatMessage);
    }

    /**
     * 修改聊天：消息
     * 
     * @param chatMessage
     * @return int
     */
    @Override
    public int updateChatMsgRead(ChatMessage chatMessage) {
        chatMessage.setUpdateTime(DateUtils.getNowDate());
        return chatMessageMapper.updateChatMsgRead(chatMessage);
    }

    /**
     * 批量删除聊天：消息
     * 
     * @param messageIds 需要删除的聊天：消息ID
     * @return 结果
     */
    @Override
    public int deleteChatMessageByIds(Long[] messageIds) {
        return chatMessageMapper.deleteChatMessageByIds(messageIds);
    }

    /**
     * 删除聊天：消息信息
     * 
     * @param messageId 聊天：消息ID
     * @return 结果
     */
    @Override
    public int deleteChatMessageById(Long messageId) {
        return chatMessageMapper.deleteChatMessageById(messageId);
    }

    /**
     * 发送消息
     * 
     * @param chatMessage
     * @return
     */
    @Override
    public ReturnVO<ChatMessageVO> sendMessage(ChatMessageDTO chatMessage) {
        Long msgFromUid = chatMessage.getMsgFromUid();
        Long msgToUid = chatMessage.getMsgToUid();
        Integer sessionType = chatMessage.getSessionType();
        Integer singleSessionType = SessionTypeEnum.SINGLE.getSessionType();
        if (Objects.equals(sessionType, singleSessionType) && Objects.equals(msgFromUid, msgToUid)) {
            throw new BaseException("不能给自己发送消息");
        }


        if(sessionType ==2){
            GroupUser groupUser=new GroupUser();
            groupUser.setUid(msgFromUid);
            groupUser.setGid(msgToUid);
            groupUser.setEstoppel(1);
            List<GroupUser> groupUsers = groupUserMapper.selectGroupUserList(groupUser);
            if(groupUsers.size() >0){
                throw new BaseException("已禁止发言");
            }
        }

//        if(sessionType ==1){
//            User user = userService.selectUserById(msgToUid);
//
//            if(user.getIsReceive()  == 1){
//                throw new BaseException("当前医生已关闭了聊天！");
//            }
//        }


        Integer chatType = chatMessage.getChatType();
        Integer toUserType = chatMessage.getUserType();
        ChatMessage message = new ChatMessage();
        BeanUtils.copyProperties(chatMessage, message);
        User user = userService.selectUserById(chatMessage.getMsgFromUid());
        User user1 = userService.selectUserById(chatMessage.getMsgToUid());
        if(user1 == null){
            throw new BaseException("消息接收人人不存在！");
        }
        toUserType = user1.getUserType();
        message.setType(user1.getUserType());
        message.setUserType(user.getUserType());



        ChatMessage chatMessage1 = new ChatMessage();
        chatMessage1.setMsgToUid(msgToUid);
        chatMessage1.setMsgFromUid(msgFromUid);
        List<ChatMessage> chatMessageList = chatMessageMapper.selectChatMessageList(chatMessage1);
        chatMessage1.setMsgToUid(msgFromUid);
        chatMessage1.setMsgFromUid(msgToUid);
        List<ChatMessage> chatMessageList2 = chatMessageMapper.selectChatMessageList(chatMessage1);
        if (( chatMessageList2.size() == 0) && ( chatMessageList.size() > 0)) {
            throw new BaseException("对方未回复只能发送一条消息");
        }


        int insertChatMessage = insertChatMessage(message);
        if (insertChatMessage > 0) {
            // 查询刚发的的消息设置会话信息
            ChatMessage newMessage = selectChatMessage(message);
            ChatMessageVO msg = new ChatMessageVO();

            BeanUtils.copyProperties(newMessage, msg);




            // 处理消息内容
            setMessage(chatMessage.getMsgFromUid(), msg);

            Integer unreadMsgCount = getUnreadMsgCount(msgFromUid, msgToUid, sessionType);

            sessionSrv.refreshSession(msgFromUid, msgToUid, chatType, user.getUserType(), toUserType, newMessage, unreadMsgCount, sessionType);

            if(sessionType ==1){
                // 用户单聊
                sendWsMessage(message, chatMessage.getMsgFromUid(), msgToUid,chatMessage.getMsgFromUid());
                // 给客户发送订单结束信息
                SubscribeMessage subscribeMessage = new SubscribeMessage();
                subscribeMessage.setTemplateId("BdgY_ehhfhW3b7YQMSjep-GZlMfGgnyJ6f-vFeCwbzY");
                String openId = user1.getUsername();
                subscribeMessage.setTouser(openId);
                subscribeMessage.setPage("pages/tabs-serve/index");
                subscribeMessage.setMiniprogramState(MiniprogramState.FORMAL);
                JSONObject data = new JSONObject();
                JSONObject value1 = new JSONObject();
                value1.put("value", user.getRealname());
                data.put("thing1", value1);

                JSONObject value4 = new JSONObject();
                if(chatMessage.getMsgType() == 1){
                    value4.put("value", chatMessage.getMsgContent());
                }
                if(chatMessage.getMsgType() == 2){
                    value4.put("value", "您有一张图片待查看");
                }
                if(chatMessage.getMsgType() == 3){
                    value4.put("value", "您有一条语音待接听");
                }
//                value4.put("value", chatMessage.getMsgContent());
                data.put("thing2", value4);
                subscribeMessage.setData(data);
                try {
                    log.info("当前开始发送消息");
                    log.info("当前开始发送消息 {}",chatMessage.getMsgContent());
                    //MiniKit.sendSubscribeMessage(MiniKit.getAccessToken().getAccessToken(), subscribeMessage);
                } catch (Exception e) {
                    log.info("当前发送消息内容异常{}",e.toString());
                    e.printStackTrace();
                }


                

            }else{
                SessionDTO sessionDTO = new SessionDTO();
                sessionDTO.setSessionType(sessionType);
                sessionDTO.setOtherSideUid(msgToUid);
                List<Session> sessions = sessionSrv.selectSessionList(sessionDTO);
                for (Session session : sessions) {
                    if(!Objects.equals(session.getUid(), chatMessage.getMsgFromUid())){
                        sendWsMessage(message, msgToUid,session.getUid(),chatMessage.getMsgFromUid());
                    }
                }
            }
            return ReturnVO.success(msg);
        } else {
            return ReturnVO.error();
        }
    }


    /**
     * 设置已读
     */
    @Override
    public int readAllMessage(ChatMessageDTO chatMessage) {
        Integer sessionType = chatMessage.getSessionType();
        Long uid = chatMessage.getMsgToUid();
        Long msgFromUid = chatMessage.getMsgFromUid();
        ChatMessage chatMessageWhere = new ChatMessage();
        chatMessageWhere.setSessionType(sessionType);
        chatMessageWhere.setMsgToUid(uid);
        chatMessageWhere.setMsgFromUid(msgFromUid);
        int updateChatMsgRead = this.updateChatMsgRead(chatMessageWhere);
        Session sessionWhere = new Session();
        sessionWhere.setSessionType(sessionType);
        sessionWhere.setUid(uid);
        sessionWhere.setOtherSideUid(msgFromUid);
        int updateSessionMsgRead = sessionSrv.updateSessionMsgRead(sessionWhere);
        return updateChatMsgRead + updateSessionMsgRead;
    }

    /**
     * 发送websoket消息
     * 
     * @author yilabao
     * @date 2021年9月29日
     * @param message
     * @param msgToUid
     */
    private void sendWsMessage(ChatMessage message, Long msgFromUid, Long msgToUid,Long from) {
        if(Objects.equals(msgFromUid, msgToUid)){
            return;
        }

        User fromUser = userSrv.selectUserById(from);
        if (fromUser == null) {
            return;
        }
        ChatMessageVO chatMessageVO = new ChatMessageVO();
        Integer msgType = message.getMsgType();
        chatMessageVO.setMsgType(msgType);
        chatMessageVO.setMsgFromUid(msgFromUid);
        chatMessageVO.setNickname(sessionSrv.getUserNickname(fromUser));
        chatMessageVO.setAvatar(WebKit.getHttpFullPath(fromUser.getAvatar()));
        chatMessageVO.setCreateTime(message.getCreateTime());
        chatMessageVO.setMessageId(message.getMessageId());
        chatMessageVO.setMsgContent(message.getMsgContent());
        chatMessageVO.setMsgExtra(message.getMsgExtra());
        chatMessageVO.setSessionType(message.getSessionType());
        chatMessageVO.setDuration(message.getDuration());
        chatMessageVO.setType(fromUser.getUserType());
        Map<String, String> userInfo = sessionSrv.getUserInfo(msgFromUid, message.getSessionType());
        chatMessageVO.setName(userInfo.get("name"));
        chatMessageVO.setPic(userInfo.get("avatar"));
        resetMsgContent(chatMessageVO);
        String messageJsonStr = JSON.toJSONStringWithDateFormat(chatMessageVO, MESSAGE_DATE_FORMAT,
                SerializerFeature.WriteDateUseDateFormat);
        ChatKit.sendMsg(msgToUid, messageJsonStr);
    }

    private void resetMsgContent(ChatMessageVO msg) {
        Integer msgType = msg.getMsgType();
        String msgContent = StringUtils.trim(msg.getMsgContent());
        if (MsgTypeEnum.TEXT.getMsgType().equals(msgType)) {
            msgContent = EmojiParser.parseToUnicode(msgContent);
        } else if (MsgTypeEnum.IMAGE.getMsgType().equals(msgType)) {
            msgContent = WebKit.getHttpFullPath(msgContent);
        }else if (MsgTypeEnum.VOICE.getMsgType().equals(msgType)) {
            msgContent = WebKit.getHttpFullPath(msgContent);
        }
        msg.setMsgContent(msgContent);
    }

    private void setMessage(Long fromUid, ChatMessageVO msg) {
        sessionSrv.getUserInfo(msg);
        resetMsgContent(msg);
        msg.setIsChatSender(Objects.equals(fromUid, msg.getMsgFromUid()));
    }

    private Integer getUnreadMsgCount(Long msgFromUid, Long msgToUid, Integer sessionType) {
        ChatMessage chatMessage = new ChatMessage();
        chatMessage.setMsgFromUid(msgFromUid);
        chatMessage.setMsgToUid(msgToUid);
        chatMessage.setSessionType(sessionType);
        return chatMessageMapper.getUnreadMsgCount(chatMessage);
    }

}